package cn.stylefeng.guns.modular.rest.storage;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.core.util.DateUtil;
import cn.stylefeng.guns.modular.basic.entity.BasicCustomer;
import cn.stylefeng.guns.modular.basic.model.params.BasicGoodsParam;
import cn.stylefeng.guns.modular.basic.model.result.BasicGoodsResult;
import cn.stylefeng.guns.modular.basic.service.BasicCustomerService;
import cn.stylefeng.guns.modular.basic.service.BasicGoodsService;
import cn.stylefeng.guns.modular.order.controller.OutOrderController;
import cn.stylefeng.guns.modular.order.entity.OutOrder;
import cn.stylefeng.guns.modular.order.model.params.*;
import cn.stylefeng.guns.modular.order.model.result.OrderTransportResult;
import cn.stylefeng.guns.modular.order.model.result.OutOrderDetailedResult;
import cn.stylefeng.guns.modular.order.model.result.OutOrderResult;
import cn.stylefeng.guns.modular.order.model.result.WhOutOrderRecordResult;
import cn.stylefeng.guns.modular.order.service.*;
import cn.stylefeng.guns.modular.replenishment.model.result.BHStorageStockResult;
import cn.stylefeng.guns.modular.storage.model.params.StorageOutParam;
import cn.stylefeng.guns.modular.storage.model.result.StorageOutResult;
import cn.stylefeng.guns.modular.storage.service.StorageOutDetailedService;
import cn.stylefeng.guns.modular.storage.service.StorageOutService;
import cn.stylefeng.roses.core.util.ToolUtil;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.stylefeng.guns.modular.rest.aop.UserAop;
import cn.stylefeng.guns.modular.storage.model.params.StorageStockParam;
import cn.stylefeng.guns.modular.storage.service.StorageStockService;
import cn.stylefeng.guns.sys.modular.system.entity.User;
import cn.stylefeng.roses.core.base.controller.BaseController;
import cn.stylefeng.roses.core.reqres.response.ResponseData;

import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * rest
 * 库存管理
 */
@Controller
@RequestMapping("/rest/storageStock")
public class reststorageStockController extends BaseController {


    @Autowired
    private StorageStockService storageStockService;
    
    @Autowired
    private UserAop userAop;
    @Autowired
    private BasicGoodsService basicGoodsService;
    @Autowired
    private WhOutOrderService whOutOrderService;

    @Autowired
    private OutOrderService outOrderService;
    @Autowired
    private OutOrderDetailedService outOrderDetailedService;
    @Autowired
    private BasicCustomerService basicCustomerService;
    @Autowired
    private StorageOutService storageOutService;
    @Autowired
    private StorageOutDetailedService storageOutDetailedService;
    @Autowired
    private OrderTransportService orderTransportService;


    @Autowired
    private WhOutOrderRecordService whOutOrderRecordService;

    private Lock lock = new ReentrantLock();
    /**
     * 查询 库存列表
     */
    @ResponseBody
    @RequestMapping("/findlist")
    public ResponseData findlist(StorageStockParam storageStockParam) {
    	User user = userAop.getUser();
    	storageStockParam.setDeptId(user.getDeptId());
    	storageStockParam.setDeliverId(user.getDeliverId());
        return ResponseData.success(this.storageStockService.findListBySpec2(storageStockParam,user.getOperateId()));
    }

    /**
     * 根据商品编码查询库存
     *
     * @return
     */
    @ResponseBody
    @RequestMapping("/findStorageStockByGoodsNumber")
    public ResponseData findStorageStockByGoodsNumber(String expressDelivery,String lastDelivery) {
//    	User user = userAop.getUser();

        // 新扫描的快递单号是否合规
        String[] lastDeliverys = lastDelivery.replaceAll("\r","").split(",");
        String[] lastDeliveryStrings = Arrays.stream(lastDeliverys).distinct().toArray(String[]::new);

        // 商品缺少库存数量
        Map<String, Double> map = new HashMap<>();
        List<ExpressDeliveryGoods> lastDeliveryStringsList =  whOutOrderService.findExpressDeliveryGoodsListBySpec(lastDeliveryStrings,122);
        if(lastDeliveryStringsList.size() <1){
            return ResponseData.error("请检查快递单号"+lastDelivery);
        }
        WhOutOrderRecordParam param = new WhOutOrderRecordParam();
        param.setExpressDelivery(lastDelivery);
        List<WhOutOrderRecordResult> listBySpec = whOutOrderRecordService.findListBySpec(param);
        if(listBySpec.size() >0){
            return ResponseData.error("快递单已合单，请勿重复扫描"+lastDelivery);
        }



        String[] split = expressDelivery.split(",");
        String[] strings = Arrays.stream(split).distinct().toArray(String[]::new);

        // 商品缺少库存数量
        List<ExpressDeliveryGoods> goodsListAll =  whOutOrderService.findExpressDeliveryGoodsListBySpec(strings,122);
        goodsListAll.forEach(goods -> {
            //根据商品编码查询拣货位库存
            BHStorageStockResult storageStockResults = basicGoodsService.findStorageStockByGoodsNumberNew("拣货位",goods.getDetailedGoodsCode(), 1970694108227276802l);

            //拣货位库存不足
            if (storageStockResults == null  ) {
                map.put(goods.getDetailedGoodsCode(), Double.valueOf(goods.getDetailedNumber()));
            }else if (Double.valueOf(storageStockResults.getNum()) < goods.getDetailedNumber()) {
                map.put(goods.getDetailedGoodsCode(), goods.getDetailedNumber() - (storageStockResults.getNum() == null ? 0 : Double.valueOf(storageStockResults.getNum())));
            }
        });

        // 商品缺少库存数量 直接提示商品缺少库存数量
        if(map.size() > 0){
            return ResponseData.error(map.toString());
        }
        return ResponseData.success();
    }



    /**
     * 确认合单
     * @return
     */
    @ResponseBody
    @RequestMapping("/confirmMerge")
    public ResponseData confirmMerge(String expressDelivery) {
        lock.lock();
    	User user = userAop.getUser();
        String account = user.getAccount();
        String[] split = expressDelivery.split(",");
        String[] splitStrings = Arrays.stream(split).distinct().toArray(String[]::new);
        for (String splitString : splitStrings) {
            if(StringUtils.isBlank(splitString)){
                continue;
            }
            WhOutOrderRecordParam param = new WhOutOrderRecordParam();
            param.setExpressDelivery(splitString);
            List<WhOutOrderRecordResult> listBySpec = whOutOrderRecordService.findListBySpec(param);
            if(listBySpec.size() >0){
                return ResponseData.error("快递单已合单，请勿重复合单"+splitString);
            }
        }

        // 商品缺少库存数量
        Map<String, Integer> map = new HashMap<>();
        List<ExpressDeliveryGoods> goodsListAll =  whOutOrderService.findExpressDeliveryGoodsListBySpec(split,122);
        goodsListAll.forEach(goods -> {
            //根据商品编码查询拣货位库存
            BHStorageStockResult storageStockResults = basicGoodsService.findStorageStockByGoodsNumberNew("拣货位",goods.getDetailedGoodsCode(), 1970694108227276802l);

            //拣货位库存不足
            if (storageStockResults == null  ) {
                map.put(goods.getDetailedGoodsCode(), goods.getDetailedNumber());
            }else if (Double.valueOf(storageStockResults.getNum()) < goods.getDetailedNumber()) {
                map.put(goods.getDetailedGoodsCode(), goods.getDetailedNumber() - (storageStockResults.getNum() == null ? 0 : Integer.valueOf(storageStockResults.getNum())));
            }
        });

        // 商品缺少库存数量 直接提示商品缺少库存数量
        if(map.size() > 0){
            return ResponseData.error(map.toString());
        }



        // 合并订单
        //创建出库单
        OutOrderParam outOrderParam= new OutOrderParam();
        outOrderParam.setDeptId(user.getDeptId());
        outOrderParam.setDeliverId(user.getDeliverId());

       String uuid = account + "-" + System.currentTimeMillis()+"";
        //客户单号
        outOrderParam.setOutCustomerId(147l);
        //客户名称
//        outOrderParam.setOutCustomerName(byId.getCustomerName());
        //仓库
        outOrderParam.setOutStorehouseId(122l);
        //仓库名称
        outOrderParam.setStorehouseName("海氏海诺武汉仓");
        //出库单号
        outOrderParam.setOutOrderNumber(uuid);
        outOrderParam.setOutWay("配送");
        outOrderParam.setTransportWay("汽运");
        outOrderParam.setOutOrderStatus("待提交");
        outOrderParam.setCreateTime(new Date());
        outOrderParam.setSetMentiontime(DateUtil.getDate());
        OutOrderResult outOrderResult = outOrderService.findbyoutOrderNumberByDeptId(uuid,null,user.getDeptId());
        outOrderParam.setCustomerNumber(uuid);
        Integer integer = outOrderService.insertOutOrder(outOrderParam);

        List<OutOrderDetailedParam> list = new ArrayList<>();

        goodsListAll.forEach(goods -> {
            OutOrderDetailedParam outOrderDetailedParam = new OutOrderDetailedParam();
            goods.getDetailedNumber(); // 数量
            goods.getDetailedGoodsCode(); // 商品编码
            goods.getDetailedGoodsName(); // 商品名称
            outOrderDetailedParam.setDetailedOutNumber(uuid);
            outOrderDetailedParam.setDetailedNumber(goods.getDetailedNumber()+"");
            outOrderDetailedParam.setDetailedGoodsname(goods.getDetailedGoodsName());
            outOrderDetailedParam.setCreateTime(new Date());
            outOrderDetailedParam.setDetailedGoodscode(goods.getDetailedGoodsCode());
            outOrderDetailedParam.setDetailedGoodsId(Long.valueOf(goods.getDetailedGoodsId()));
            list.add(outOrderDetailedParam);
        });
        outOrderDetailedService.saveBatchList(list);
        Long[] ids = {Long.valueOf(outOrderParam.getId())};
        submitsWhHshn(ids);
        int boxNumber = 1;
        for (String s : split) {
            if(StringUtils.isBlank(s)){
                continue;
            }

            WhOutOrderRecordParam param = new WhOutOrderRecordParam();
            param.setExpressDelivery(s);
            param.setOutOrderNumber(uuid);
            param.setBoxNumber(boxNumber);
            whOutOrderRecordService.add(param);
            boxNumber++;
        }
        lock.unlock();//释放锁
        return ResponseData.success();
    }


    ResponseData submitsWhHshn(Long[] ids)
    {
        ResponseData data = new ResponseData();
        data.setSuccess(true);
        OutOrderParam param = new OutOrderParam();
        User user  = userAop.getUser();
        lock.lock();//获取锁
        try {
            for (Long id : ids) {
                OutOrder outOrder = outOrderService.getById(id);
                if (!"待提交".equals(outOrder.getOutOrderStatus())&&!"撤回".equals(outOrder.getOutOrderStatus())) {
                    continue;
                }
                OutOrderDetailedParam outOrderDetailedParam = new OutOrderDetailedParam();
                outOrderDetailedParam.setDetailedOutNumber(outOrder.getOutOrderNumber());
                List<OutOrderDetailedResult> list = outOrderDetailedService.findListBySpec(outOrderDetailedParam);
                if (list.size()==0) {
                    data.setSuccess(false);
                    data.setMessage("请先添加商品明细");
                    return data;
                }
                //提交时间
                outOrder.setSubmitTime(new Date());
                //提交人名称
                outOrder.setSubmitterName(user.getName());
                BasicCustomer basicCustomer = basicCustomerService.getById(outOrder.getOutCustomerId());
                if(ToolUtil.isNotEmpty(basicCustomer.getOutorderconfirm()) && basicCustomer.getOutorderconfirm().equals("是")) {
                    storageOutDetailedService.checkStock(outOrder,data);//校验库存
                    if(!data.getSuccess()){
                        return data;
                    }
                } else {
                    storageOutDetailedService.outSingleWhHSHN(outOrder,data);//生成拣货单
                    if(!data.getSuccess()){
                        return data;
                    }


                    StorageOutParam storageOutParam = new StorageOutParam();
                    storageOutParam.setStorageOutNumber(outOrder.getCustomerNumber());
                    StorageOutResult storageOutResult = storageOutService.findBySpec(storageOutParam);
                    if(ToolUtil.isEmpty(storageOutResult)){
                        continue;
                    }
                    List<StorageOutResult> listr = new ArrayList<StorageOutResult>();
                    listr.add(storageOutResult);
                    data = storageOutDetailedService.recommend(listr);//出库推荐库位 （~  . ~  ）***
                    if (!data.getSuccess()) {
                        return data;
                    }
                }

                if(outOrder.getOutWay().equals("配送")){
                    ToolUtil.copyProperties(outOrder,param);
                    orderTransportService.outUpdateTransport(param);
                    OrderTransportParam orderTransportParam = new OrderTransportParam();
                    orderTransportParam.setCustomerOrder(param.getCustomerNumber());
                    OrderTransportResult orderTransportResult = orderTransportService.findBySpec(orderTransportParam,null);
                    if(orderTransportResult != null) {
                        orderTransportService.auditorder(orderTransportResult.getId());
                    }
                }
                param = new OutOrderParam();
                outOrder = new OutOrder();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();//释放锁
        }
        return data;
    }

    public static void main(String[] args) {
        long l = System.currentTimeMillis();
        System.out.println(l);
    }
}
